package com.zeny.coding.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zeny.coding.constants.CourseConstants;
import com.zeny.coding.dto.PageDto;
import com.zeny.coding.dto.SmsDto;
import com.zeny.coding.enmus.SmsStatusEnum;
import com.zeny.coding.entity.Sms;
import com.zeny.coding.entity.SmsExample;
import com.zeny.coding.mapper.SmsMapper;
import com.zeny.coding.service.EmailService;
import com.zeny.coding.service.SmsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <h2>手机服务</h2>
 *
 * @Author Zeny
 */

@Service
public class SmsServiceImpl implements SmsService {

    @Autowired
    private SmsMapper smsMapper;

    @Autowired
    private EmailService emailService;

    @Override
    public void list(PageDto<SmsDto> pageDto) {
        //分页
        PageHelper.startPage(pageDto.getPage(), pageDto.getSize());
        //设置条件
        SmsExample smsExample = new SmsExample();
        smsExample.setOrderByClause("at desc");
        //查询结果
        List<Sms> smsList = this.smsMapper.selectByExample(smsExample);
        PageInfo<Sms> pageInfo = new PageInfo<>(smsList);
        //设置总条数
        pageDto.setTotal(pageInfo.getTotal());
        //封装成DTO传输
        List<SmsDto> smsDtoList = new ArrayList<>();
        for (Sms sms : smsList) {
            SmsDto smsDto = new SmsDto();
            BeanUtils.copyProperties(sms, smsDto);
            smsDtoList.add(smsDto);
        }
        //设置记录数
        pageDto.setList(smsDtoList);
    }

    @Transactional(rollbackFor = Exception.class)
    @SuppressWarnings("all")
    @Override
    public void sendCode(SmsDto smsDto) throws Exception {
        SmsExample example = new SmsExample();
        SmsExample.Criteria criteria = example.createCriteria();
        criteria.andMobileEqualTo(smsDto.getMobile());
        //设置条件: 注册还是忘记密码
        criteria.andUseEqualTo(smsDto.getUse());
        //设置条件: 使用还是未使用
        criteria.andStatusEqualTo(SmsStatusEnum.NOT_USED.getKey());
        //一分钟内
        criteria.andAtGreaterThan(new Date(System.currentTimeMillis() - 2 * 60 * 1000));
        List<Sms> smsList = smsMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(smsList)) {
            //一分钟内没有发短信
            saveAndSend(smsDto);
        } else {
            //一分钟内发送过短信
            throw new RuntimeException(CourseConstants.SMS_CAN_NOT_SEND_IN_1MIN);
        }
    }

    /**
     * <h2>保存并发送验证码</h2>
     * @param
     * @param smsDto
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAndSend(SmsDto smsDto) throws Exception {
        //1、保存验证码
        //6位数字验证码
        String code = String.valueOf((int)((Math.random() * 9 + 1) * 100000));
        smsDto.setAt(new Date());
        smsDto.setCode(code);
        //设置使用状态: 未使用
        smsDto.setStatus(SmsStatusEnum.NOT_USED.getKey());
        save(smsDto);
        //2、发送验证码
        //todo
        emailService.sendEmail(smsDto.getMobile(), code);
    }

    @Override
    public SmsDto findSmsByMobile(SmsDto smsDto) {
        SmsExample example = new SmsExample();
        SmsExample.Criteria criteria = example.createCriteria();
        criteria.andMobileEqualTo(smsDto.getMobile());
        //设置条件: 注册 | 忘记密码
        criteria.andUseEqualTo(smsDto.getUse());
        //设置条件: 使用还是未使用
        criteria.andStatusEqualTo(SmsStatusEnum.NOT_USED.getKey());
        //2分钟内
        criteria.andAtGreaterThan(new Date(System.currentTimeMillis() - 2 * 60 * 1000));
        List<Sms> list = smsMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        Sms sms = list.get(0);
        BeanUtils.copyProperties(sms, smsDto);
        return smsDto;
    }

    @SuppressWarnings("all")
    @Transactional
    @Override
    public void updateStatus(String mobile, String smsCode) {
        SmsExample example = new SmsExample();
        SmsExample.Criteria criteria = example.createCriteria();
        criteria.andMobileEqualTo(mobile);
        criteria.andCodeEqualTo(smsCode);
        Sms sms = new Sms();
        sms.setStatus(SmsStatusEnum.USED.getKey());
        smsMapper.updateByExampleSelective(sms, example);
    }

    /**
     * <h2>保存短信验证码</h2>
     * @param smsDto
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SmsDto smsDto) {
        Sms sms = new Sms();
        BeanUtils.copyProperties(smsDto, sms);
        String id = UUID.randomUUID().toString().substring(0, 8);
        sms.setId(id);
        this.smsMapper.insertSelective(sms);
    }
}
